#pragma once
#include <imgui.h>
#include <utl/vector.h>
#include <string>
#include <common_header.h>
#include <utl/memory.h>
#include <utl/io.h>
#include <array>

struct GLFWwindow;

namespace primal
{
	enum MENU_GROUP : u32
	{
		MENU_GROUP_FILE,
		MENU_GROUP_VIEW,
		MENU_GROUP_EDITOR,
		MENU_GROUP_PROJECT,
		MENU_GROUP_DEBUG,
		MENU_GROUP_TEST,
		MENU_GROUP_TOOLS,
		MENU_GROUP_EXTENTIONS,
		MENU_GROUP_WINDOW,
		MENU_GROUP_HELP,
		MENU_GROUP_ABOUT,
		MENU_GROUP_OTHER,
		MENU_GROUP_MAX,
	};

	using FontList = utl::vector<ImFont*>;

	class Menu
	{
	public:
		Menu(const std::string& t, MENU_GROUP mg = MENU_GROUP_OTHER);
		virtual ~Menu();
		virtual void render(const FontList& ) = 0;//DELETE
		virtual void content() {};
	protected:
		std::string title;
	private:
		MENU_GROUP group;
	};

	class WindowViewMenu : public Menu
	{
	public:
		WindowViewMenu(const std::string& t);
		void render(const FontList&) override;
		void binding_window(bool* wl);
	private:
		bool* window_life;
	};

	enum FontType : u32
	{
		FontType_Min,
		FontType_Max,
		FontType_Font_Max,
		FontType_Count,
	};

	class GuiWindowBase
	{
	public:
		GuiWindowBase(const std::string& tit, bool default_show = true);
		virtual ~GuiWindowBase();
		void render(const FontList& icon_ft);
	private:
		virtual void content(const FontList& icon_ft) = 0;
	private:
		WindowViewMenu menu;
		std::string title;
		bool is_show;
	};

	namespace gui
	{
		using Window_FN = void(*)(const FontList& icon_ft, bool* life);
		using Menu_FN = void(*)(const FontList& icon_ft);

		void render();
		void impl_new_frame();
		void impl_draw();

		bool initialize(GLFWwindow* window);
		bool impl_initialize(GLFWwindow* window);

		void register_window(Window_FN fn, const char*, const char*);
		void register_menu(Menu_FN, const char*, MENU_GROUP);

		void gui_shutdown();
		void gui_impl_shutdown();

		void set_theme_blender();
		void set_theme_cyberpunk();
		void set_theme_nord();
		void set_theme_moonlight();
	}

	namespace ImGuiEx
	{
		using input_buffer = std::array<char, 256>;
		bool InputWindow(const char* title, input_buffer& out_buf, bool fo);
		void DrawVec3(const char* lable, float* values, float reset_value, float columnWidth);
	}
}